import clsx from 'clsx';
import * as PropTypes from 'prop-types';
import React, { forwardRef } from 'react';
import styles from './index.less';

Box = forwardRef(Box);

/** 简易样式组件 */
function Box(props, ref) {
  const {
    className,
    component: Comp = 'div',
    px,
    py,
    mx,
    my,
    fz,
    flex,
    ali,
    jus,
    sali,
    sjus,
    grow,
    shrink,
    wrap,
    dir,
    scroll,
    ...rest
  } = props;

  const klassName = clsx(
    styles.box,
    styles[`px${px}`.replace(/\./g, '')],
    styles[`py${py}`.replace(/\./g, '')],
    styles[`mx${mx}`.replace(/\./g, '')],
    styles[`my${my}`.replace(/\./g, '')],
    styles[`my${fz}`],
    {
      [styles.flex]: flex,
      [styles.inline]: flex === 'inline',
      [styles.scroll]: scroll,
      [styles.grow]: grow,
    },
    typeof shrink === 'boolean' && {
      [styles.shrink]: shrink,
      [styles.noShrink]: !shrink,
    },
    styles[wrap],
    styles[`ali${ali}`],
    styles[`jus${jus}`],
    styles[`sali${sali}`],
    styles[`sjus${sjus}`],
    styles[dir?.replace(/-\w/g, (t) => t.slice(-1).toUpperCase())],
    className,
  );

  return <Comp ref={ref} className={klassName} {...rest} />;
}

Box.propTypes = {
  component: PropTypes.elementType,

  /** X axis padding */
  px: PropTypes.oneOf([0.5, 1, 2, 3]),

  /** Y axis padding */
  py: PropTypes.oneOf([0.5, 1, 2, 3]),

  /** X axis margin */
  mx: PropTypes.oneOf([0.5, 1, 2, 3, 'auto']),

  /** Y axis margin */
  my: PropTypes.oneOf([0.5, 1, 2, 3]),

  /** font size */
  fz: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']),

  /** flex container */
  flex: PropTypes.oneOf([true, 'inline']),

  /** align-item */
  ali: PropTypes.oneOf(['start', 'center', 'end', 'stretch']),

  /** justify-content */
  jus: PropTypes.oneOf(['start', 'center', 'end', 'stretch', 'around', 'between', 'evenly']),

  /** align-self */
  sali: PropTypes.oneOf(['start', 'center', 'end', 'stretch']),

  /** justify-self */
  sjus: PropTypes.oneOf(['start', 'center', 'end', 'stretch', 'around', 'between', 'evenly']),

  /** flex-grow */
  grow: PropTypes.bool,

  /** flex-shrink */
  shrink: PropTypes.bool,

  /** flex-wrap */
  wrap: PropTypes.bool,

  /** flex-direction */
  dir: PropTypes.oneOf(['row', 'col', 'row-rev', 'col-rev']),

  /** overflow scroll */
  scroll: PropTypes.bool,
};

export default Box;
